////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// The MIT License (MIT)                                                      //
//                                                                            //
// Copyright (c) 2013 Charles Teague                                          //
//                                                                            //
// Permission is hereby granted, free of charge, to any person obtaining a    //
// copy of this software and associated documentation files (the "Software"), //
// to deal in the Software without restriction, including without limitation  //
// the rights to use, copy, modify, merge, publish, distribute, sublicense,   //
// and/or sell copies of the Software, and to permit persons to whom the      //
// Software is furnished to do so, subject to the following conditions:       //
//                                                                            //
// The above copyright notice and this permission notice shall be included in //
// all copies or substantial portions of the Software.                        //
//                                                                            //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    //
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    //
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        //
// DEALINGS IN THE SOFTWARE.                                                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.IO;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


using RPSDAL;
using RPSDAL.CollectionClasses;
using RPSDAL.EntityClasses;
using RPSDAL.HelperClasses;
using RPSDAL.DaoClasses;

using SD.LLBLGen.Pro.ORMSupportClasses;

public partial class ContactList : System.Web.UI.Page
{
    #region on load

    protected override void OnInit(EventArgs e)
    {
        ShowExtraFields();
    }

    /// <summary>
    /// load contacts
    /// </summary>
    private void LoadContacts()
    {
        ContactCollection cContacts = new ContactCollection();
        IPredicateExpression filter = new PredicateExpression();
     //   filter.Add(ContactFields.Active == true);

        if (Parameters.LoggedUser != -1)
        {
            UserEntity eUser = new UserEntity(Parameters.LoggedUser);            
            if (!eUser.ViewAllContacts)
            {
                // show only contact created by the user, else show all contacts
                filter.AddWithAnd(ContactFields.UserId == Parameters.LoggedUser);
            }

            // hide edit contact
            eUser = new UserEntity(Parameters.LoggedUser);
            RoleEntity eRole = new RoleEntity(eUser.RoleId);

            if (!eRole.HasViewContact)
            {

                Parameters.LoggedUser = -1;
                Response.Redirect("Default.aspx");
                return;
            }

            if (!eRole.HasEditContact)
            {
                grdContacts.Columns[3].Visible = false;
                grdContacts.Columns[4].Visible = false;
                btnAddNewContact.Visible = false;
            }
        }
        cContacts.GetMulti(filter);

        grdContacts.DataSource = cContacts;
        grdContacts.DataBind();

        
    }

    /// <summary>
    /// initialize page
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            // load contacts
            grdContacts.PageSize = Parameters.PageSize; 
            LoadContacts();

            ContactTypeCollection cContactTypes = new ContactTypeCollection();
            cContactTypes.GetMulti(null);

            ddlContactType.DataSource = cContactTypes;
            ddlContactType.DataTextField = "Name";
            ddlContactType.DataValueField = "ContactTypeId";
            ddlContactType.DataBind();

            ddlContactType.Items.Insert(0, "");
            ddlContactType.SelectedIndex = 0;

        }
    }

    #endregion on load

    #region user interface

    protected void ShowSearch(object sender, EventArgs e)
    {        
        if (Search())
        {
            pnlContactList.Visible = true;
            pnlSearch.Visible = false;
        }
        else
        {
            lblSearchResult.Text = "No contacts found.";
        }
    }

    protected void Cancel(object sender, EventArgs e)
    {
        pnlContactList.Visible = true;
        pnlSearch.Visible = false;        
    }

    #region load states

    private void LoadStates()
    {
        try
        {
            DataSet ds = new DataSet();
            ds.ReadXml(Methods.AppRoot + "\\Data\\states.xml");
            cmbStates.DataSource = ds.Tables[0];
            cmbStates.DataTextField = ds.Tables[0].Columns[0].ColumnName;
            cmbStates.DataValueField = ds.Tables[0].Columns[0].ColumnName;
            cmbStates.DataBind();
        }
        catch { }
    }

    #endregion load states

    #region load countries

    private void LoadCountries()
    {
        try
        {
            DataSet ds = new DataSet();
            ds.ReadXml(Methods.AppRoot + "\\Data\\countries.xml");
            cmbCountry.DataSource = ds.Tables[0];
            cmbCountry.DataTextField = ds.Tables[0].Columns[0].ColumnName;
            cmbCountry.DataValueField = ds.Tables[0].Columns[0].ColumnName;
            cmbCountry.DataBind();


            cmbCountry.Items.Insert(0,"Choose a country...");

            
        }
        catch { }
    }

    #endregion load countries

    protected void RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Button button = (Button)e.Row.FindControl("btnRemove");
            button.Attributes.Add("onclick", @"javascript:return confirm('Are you sure you want to delete this contact? This will delete everything related to it (letters, history, etc.). ');");
        }
    }

    protected void OpenSearch(object sender, EventArgs e)
    {
        LoadCountries();
        LoadStates();

        InitSearch();
        pnlContactList.Visible = false;
        pnlSearch.Visible = true;
    }

    /// <summary>
    /// initialize components for a new search
    /// </summary>
    private void InitSearch() 
    {
        lblSearchResult.Text = "";

        ddlContactType.SelectedIndex = 0;
        txtName.Text = "";
        txtEmail.Text = "";
        txtPhone.Text = "";
        txtMobilePhoneNo.Text = "";
        txtFax.Text = "";
        txtMailAddress.Text = "";
        txtCity.Text = "";
        txtZip.Text = "";
        cmbStates.SelectedIndex = 0;
        cmbCountry.SelectedIndex = 0;
        txtVisitDateFrom.Text = "";
        txtVisitDateTo.Text = "";
        ckActive.Checked = true;
        ckInactive.Checked = true;

        for (int i = 0; i < grdFields.Rows.Count; i++)
        {
            int contactPageFieldId = Convert.ToInt32(((TextBox)grdFields.Rows[i].Cells[2].FindControl("id")).Text);
            switch (Convert.ToInt32(grdFields.Rows[i].Cells[1].Text))
            {
                case Parameters.TEXTBOX_TYPE:
                case Parameters.DATETIME_TYPE:
                case Parameters.TEXTAREA_TYPE:
                    ((TextBox)grdFields.Rows[i].Cells[1].Controls[0]).Text = "";
                    break;
                case Parameters.COMBOBOBOX_TYPE:
                    ((DropDownList)grdFields.Rows[i].Cells[1].Controls[0]).SelectedIndex = 0;
                    break;
                case Parameters.CHECKBOX_TYPE:
                    ((CheckBox)grdFields.Rows[i].Cells[1].Controls[0]).Checked = false;
                    break;
            }

        }
    }


    protected void Command(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "Page")
        {
            return;
        }
        switch (((System.Web.UI.WebControls.Button)(e.CommandSource)).Text)
        {
            case "Edit":                
                Global.UserLogSave(Parameters.LoggedUser, "Edit Contact id="+e.CommandArgument.ToString());
                Response.Redirect("Contact.aspx?id=" + Global.EncryptString(e.CommandArgument.ToString()));
                break;
            case "Remove":
                Global.UserLogSave(Parameters.LoggedUser, "Remove Contact id="+e.CommandArgument.ToString());
                ContactEntity eContact = new ContactEntity(Convert.ToInt32(e.CommandArgument));
                ContactFileCollection cContactFiles = new ContactFileCollection();
                IPredicateExpression filter = new PredicateExpression();
                filter.Add(ContactFileFields.ContactId == eContact.ContactId);
                cContactFiles.GetMulti(filter);

                // delete contact files
                for (int i = 0; i < cContactFiles.Count; i++)
                {
                    if (File.Exists(cContactFiles[i].ServerFile))
                    {
                        File.Delete(cContactFiles[i].ServerFile);
                    }
                }

                cContactFiles.DeleteMulti(filter);


                CallCollection cCalls = new CallCollection();
                filter = new PredicateExpression();
                filter.Add(CallFields.ContactId == eContact.ContactId);
                cCalls.DeleteMulti(filter);
                


                ContactGroupMemberCollection cContactGroupMembers = new ContactGroupMemberCollection();
                filter = new PredicateExpression();
                filter.Add(ContactGroupMemberFields.ContactId == eContact.ContactId);
                cContactGroupMembers.DeleteMulti(filter);

                eContact.Delete();
                Response.Redirect("ContactList.aspx");
                break;
            case "View history":
                Global.UserLogSave(Parameters.LoggedUser, "View History Contact id="+e.CommandArgument.ToString());
                Response.Redirect("ContactHistory.aspx?id=" + Global.EncryptString(e.CommandArgument.ToString()));
                break;
        }
    }
    protected void AddNewContact(object sender, EventArgs e)
    {
        Global.UserLogSave(Parameters.LoggedUser, "Add New Contact");       
        Response.Redirect("Contact.aspx");
    }

    #endregion user interface


    #region actions

    protected bool Search()
    {
        ContactCollection cContacts = new ContactCollection();

        IPredicateExpression filter = new PredicateExpression();

        #region static fields

        if (ddlContactType.SelectedItem.Text != "")
        {
            filter.Add(ContactFields.ContactTypeId == ddlContactType.SelectedValue);
        }
        if (txtName.Text != "")
        {
            filter.AddWithAnd(ContactFields.Name % ("%" + txtName.Text + "%"));
        }
        if (txtEmail.Text != "")
        {
            filter.AddWithAnd(ContactFields.EmailAddress % ("%" + txtEmail.Text + "%"));
        }
        if (txtPhone.Text != "")
        {
            filter.AddWithAnd(ContactFields.Phone % ("%" + txtPhone.Text + "%"));
        }
        if (txtMobilePhoneNo.Text != "")
        {
            filter.AddWithAnd(ContactFields.MobilePhone % ("%" + txtMobilePhoneNo.Text + "%"));
        }
        if (txtFax.Text != "")
        {
            filter.AddWithAnd(ContactFields.Fax % ("%" + txtFax.Text + "%"));
        }
        if (txtMailAddress.Text != "")
        {
            filter.AddWithAnd(ContactFields.MailAddress % ("%" + txtMailAddress.Text + "%"));
        }
        if (txtCity.Text != "")
        {
            filter.AddWithAnd(ContactFields.MailCity % ("%" + txtCity.Text + "%"));
        }
        if (cmbStates.SelectedItem != null && cmbStates.SelectedItem.Text != "Choose a state...")
        {
            filter.AddWithAnd(ContactFields.MailState == cmbStates.SelectedItem.Text);
        }
        if (cmbCountry.SelectedItem != null && cmbCountry.SelectedItem.Text != "Choose a country...")
        {
            filter.AddWithAnd(ContactFields.MailCountry == cmbCountry.SelectedItem.Text);
        }
        if (txtZip.Text != "")
        {
            filter.AddWithAnd(ContactFields.MailZip % ("%" + txtZip.Text + "%"));
        }

        if (!(ckActive.Checked && ckInactive.Checked))
        {
            if (ckActive.Checked)
            {
                filter.AddWithAnd(ContactFields.Active == true);
            }
            else 
            {
                if (!ckInactive.Checked)
                {
                    return false;
                }
            }

            if (ckInactive.Checked)
            {
                filter.AddWithAnd(ContactFields.Active == false);
            }
        }

        try
        {
            if (txtVisitDateFrom.Text != "")
            {
                filter.AddWithAnd(ContactFields.ContactVisitDate >= DateTime.Parse(txtVisitDateFrom.Text));
            }
            if (txtVisitDateTo.Text != "")
            {
                filter.AddWithAnd(ContactFields.ContactVisitDate <= DateTime.Parse(txtVisitDateTo.Text));
            }
        }
        catch { };

        #endregion static fields


        cContacts.GetMulti(filter);
        if (cContacts.Count > 0)
        {
            for (int k = cContacts.Count-1; k >=0; k--)
            {

                // save extra fields
                for (int i = 0; i < grdFields.Rows.Count; i++)
                {
                    int contactPageFieldId = Convert.ToInt32(((TextBox)grdFields.Rows[i].Cells[2].FindControl("id")).Text);
                    AvailableToContactTypeCollection cAvailableToContactType = new AvailableToContactTypeCollection();
                    IPredicateExpression filterContactType = new PredicateExpression();
                    filterContactType.Add(AvailableToContactTypeFields.ContactTypeId == cContacts[k].ContactTypeId);
                    filterContactType.Add(AvailableToContactTypeFields.ContactPageFieldId == contactPageFieldId);

                    string fieldValue = "";
                    switch (Convert.ToInt32(grdFields.Rows[i].Cells[1].Text))
                    {
                        case Parameters.TEXTBOX_TYPE:
                        case Parameters.DATETIME_TYPE:
                        case Parameters.TEXTAREA_TYPE:
                            fieldValue = ((TextBox)grdFields.Rows[i].Cells[1].Controls[0]).Text;
                            break;
                        case Parameters.COMBOBOBOX_TYPE:
                            fieldValue = ((DropDownList)grdFields.Rows[i].Cells[1].Controls[0]).SelectedValue;
                            if (fieldValue == "Choose...")
                            {
                                fieldValue = "";
                            }
                            break;
                        case Parameters.CHECKBOX_TYPE:
                            fieldValue = ((CheckBox)grdFields.Rows[i].Cells[1].Controls[0]).Checked.ToString();
                            break;
                    }

                    if (cAvailableToContactType.GetDbCount(filterContactType) == 1)
                    {   
                        if (fieldValue.Trim() != "")
                        {
                            ContactFieldCollection cContactFields = new ContactFieldCollection();
                            IPredicateExpression filterFields = new PredicateExpression();
                            filterFields.Add(ContactFieldFields.ContactPageFieldId == contactPageFieldId);
                            filterFields.Add(ContactFieldFields.FieldValue % ("%" + fieldValue + "%"));
                            filterFields.Add(ContactFieldFields.ContactId == cContacts[k].ContactId);

                            if (cContactFields.GetDbCount(filterFields) == 0)
                            {
                                cContacts.Remove(cContacts[k]);
                                break;
                            }
                        }
                    }
                    else 
                    {
                        if (fieldValue.Trim() != "" && fieldValue.ToUpper() != "FALSE" && fieldValue.ToUpper() != "TRUE")
                        {
                            cContacts.Remove(cContacts[k]);
                            break;
                        }
                    }
                }
            }

            if (cContacts.Count > 0)
            {
                grdContacts.DataSource = cContacts;
                grdContacts.DataBind();
                return true;
            }
            else 
            {
                return false;
            }
        }
        else
        {
            return false;
        }

        #region old
        /*
        IPredicateExpression filterDynamic = new PredicateExpression();
        bool filterIndicator = false;

        // save extra fields
        for (int i = 0; i < grdFields.Rows.Count; i++)
        {
            int contactPageFieldId = Convert.ToInt32(((TextBox)grdFields.Rows[i].Cells[2].FindControl("id")).Text);
            string fieldValue = "";
            switch (Convert.ToInt32(grdFields.Rows[i].Cells[1].Text))
            {
                case Parameters.TEXTBOX_TYPE:
                case Parameters.DATETIME_TYPE:
                case Parameters.TEXTAREA_TYPE:
                    fieldValue = ((TextBox)grdFields.Rows[i].Cells[1].Controls[0]).Text;
                    break;
                case Parameters.COMBOBOBOX_TYPE:
                    fieldValue = ((DropDownList)grdFields.Rows[i].Cells[1].Controls[0]).SelectedValue;
                    if (fieldValue == "Choose...") 
                    {
                        fieldValue = "";
                    }
                    break;
                case Parameters.CHECKBOX_TYPE:
                    fieldValue = ((CheckBox)grdFields.Rows[i].Cells[1].Controls[0]).Checked.ToString();
                    break;
            }

            if (fieldValue.Trim() != "")
            {
                ContactFieldCollection cContactPageFields = new ContactFieldCollection();
                IPredicateExpression filterFields = new PredicateExpression();
                filterFields.Add(ContactFieldFields.ContactPageFieldId == contactPageFieldId);
                filterFields.Add(ContactFieldFields.FieldValue % ("%" + fieldValue + "%"));
                cContactPageFields.GetMulti(filterFields);

                for (int j = 0; j < cContactPageFields.Count; j++)
                {
                    filterDynamic.AddWithOr(ContactFields.ContactId == cContactPageFields[j].ContactId);                    
                }

                filterIndicator = true;
            }


        }

        if (filterDynamic.Count == 0 && filterIndicator)
        {
            return false;
        }

        filter.AddWithAnd(filterDynamic);
        cContacts.GetMulti(filter);

        if (cContacts.Count > 0)
        {
            grdContacts.DataSource = cContacts;
            grdContacts.DataBind();
            return true;
        }
        else 
        {
            return false;
        }
        */
        #endregion old
    }

    protected void grdContacts_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        grdContacts.PageIndex = e.NewPageIndex;
        LoadContacts();
    }

    #endregion actions

    #region search

    private void ShowExtraFields()
    {

        // load contact type fields
        DataTable dtFields = Fields();
        grdFields.DataSource = dtFields;
        grdFields.DataBind();

        for (int i = 0; i < grdFields.Rows.Count; i++)
        {
            try
            {
                switch (Convert.ToInt32(grdFields.Rows[i].Cells[1].Text))
                {
                    case Parameters.TEXTBOX_TYPE:
                        //textbox
                        TextBox txtTextBox = new TextBox();
                        txtTextBox.Width = new Unit(60, UnitType.Percentage);
                        grdFields.Rows[i].Cells[1].Controls.Add(txtTextBox);
                        break;
                    case Parameters.COMBOBOBOX_TYPE:
                        // combobox
                        ContactPageDropdownFieldValueCollection cComboboxValues = new ContactPageDropdownFieldValueCollection();
                        IPredicateExpression filter = new PredicateExpression();
                        filter.Add(ContactPageDropdownFieldValueFields.ContactPageFieldId == Convert.ToInt32(((TextBox)grdFields.Rows[i].Cells[1].FindControl("id")).Text));
                        cComboboxValues.GetMulti(filter);

                        DropDownList cmbComboBox = new DropDownList();
                        cmbComboBox.DataSource = cComboboxValues;
                        cmbComboBox.DataValueField = ContactPageDropdownFieldValueFields.Value.Name;
                        cmbComboBox.DataTextField = ContactPageDropdownFieldValueFields.Value.Name;
                        cmbComboBox.DataBind();

                        cmbComboBox.Items.Insert(0, "Choose...");

                        cmbComboBox.Width = new Unit(60, UnitType.Percentage);
                        grdFields.Rows[i].Cells[1].Controls.Add(cmbComboBox);
                        break;
                    case Parameters.CHECKBOX_TYPE:
                        CheckBox ckCehckBox = new CheckBox();
                        grdFields.Rows[i].Cells[1].Controls.Add(ckCehckBox);
                        break;
                    case Parameters.TEXTAREA_TYPE:
                        TextBox txtTextArea = new TextBox();
                        txtTextArea.TextMode = TextBoxMode.MultiLine;
                        txtTextArea.Width = new Unit(60, UnitType.Percentage);
                        grdFields.Rows[i].Cells[1].Controls.Add(txtTextArea);
                        break;
                    case Parameters.DATETIME_TYPE:
                        TextBox txtDateTime = new TextBox();
                        txtDateTime.ID = "txtDateTimeId";
                        grdFields.Rows[i].Cells[1].Controls.Add(txtDateTime);
                        Image imgDateTime = new Image();
                        imgDateTime.ImageUrl = "jscripts/date/calendar.gif";
                        imgDateTime.ID = "dateId";
                        grdFields.Rows[i].Cells[1].Controls.Add(imgDateTime);
                        break;
                }
            }
            catch { }

        }
    }

    /// <summary>
    ///  get fields to be filled in
    /// </summary>
    /// <param name="contactTypeId"></param>
    /// <returns></returns>
    private DataTable Fields()
    {
        DataTable dtFields = new DataTable();

        ResultsetFields fields = new ResultsetFields(4);
        fields.DefineField(ContactPageFieldFieldIndex.Name, 0, "Name");
        fields.DefineField(ContactPageFieldFieldIndex.Type, 1, "Type");
        fields.DefineField(ContactPageFieldFieldIndex.OrderIndex, 2, "OrderIndex");
        fields.DefineField(ContactPageFieldFieldIndex.ContactPageFieldId, 3, "ContactPageFieldId");

        RelationCollection relations = new RelationCollection();
        TypedListDAO dao = new TypedListDAO();
        SortExpression sortExp = new SortExpression(new SortClause(fields["OrderIndex"], SortOperator.Ascending));
        dao.GetMultiAsDataTable(fields, dtFields, 0, sortExp, null, relations, false, null, null, 0, 0);

        return dtFields;
    }

   


    #endregion search
}
